﻿using OpenAiMobile.Models;
using OpenAiMobile.Repositories;
using OpenAiMobile.Tools;
using OpenAiMobile.Util.Extensions;
using OpenAiMobile.Util.Services;

namespace OpenAiMobile.Services
{
    public class ConfigService : IConfigService
    {
        public string WebApiUrl => $@"http://{ServerIp}:{ServerPort}";
        public string ServerIp { get; private set; }
        public int ServerPort { get; private set; }
        public int RequestTimeout { get; private set; }
        public string AesKey { get; private set; }

        public string ApiKey { get; private set; }
        public string AccountId { get; private set; }

        /// <summary>
        /// APP数据文件夹
        /// </summary>
        public string AppDataDirectory { get; }

        private readonly ILogService _logService;
        private readonly IContainerProvider _container;

        public ConfigService(
            ILogService logService,
            IContainerProvider container
        )
        {
            _logService = logService;
            _container = container;

            //APP数据文件夹
            var path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            var app = typeof(ConfigService).Namespace?.Split('.').FirstOrDefault();
            AppDataDirectory = Path.Combine(path, app ?? string.Empty);

            //创建文件夹
            CreateDirectory(AppDataDirectory);
        }

        private void CreateDirectory(string path)
        {
            if (!string.IsNullOrWhiteSpace(path) && !Directory.Exists(path))
            {
                try
                {
                    Directory.CreateDirectory(path);
                }
                catch (Exception e)
                {
                    _logService.Error($"创建文件夹{path}失败：{e.GetFullMessage()}.");
                }
            }
        }

        #region 加载参数

        public async Task LoadConfigAsync()
        {
            try
            {
                var repository = _container.Resolve<IRepository<ConfigModel>>();
                AccountId = await GetConfigValue(
                    repository,
                    Constants.ConfigKeys.AccountId,
                    ""
                );
                AesKey = await GetConfigValue(
                    repository,
                    Constants.ConfigKeys.AesKey,
                    Constants.ConfigValues.AesKey
                );
                //ApiKey = await GetConfigValue(
                //    repository,
                //    Constants.ConfigKeys.ApiKey,
                //    Constants.ConfigValues.ApiKey
                //);
                ServerIp = await GetConfigValue(
                    repository,
                    Constants.ConfigKeys.ServerIp,
                    Constants.ConfigValues.ServerIp
                );
                ServerPort = await GetConfigValueInt(
                    repository,
                    Constants.ConfigKeys.ServerPort,
                    Constants.ConfigValues.ServerPort);
                RequestTimeout = await GetConfigValueInt(
                    repository,
                    Constants.ConfigKeys.RequestTimeout,
                    Constants.ConfigValues.RequestTimeout);
            }
            catch (Exception e)
            {
                _logService.Error($"加载配置失败：{e.GetFullMessage()}.");
            }
        }

        private async Task<int> GetConfigValueInt(
            IRepository<ConfigModel> repository,
            string key,
            int defaultValue)
        {
            var modelList = await repository.GetAsync(t => t.Key == key);
            if (!modelList.Any())
            {
                return defaultValue;
            }

            var value = modelList.FirstOrDefault()?.Value;
            return int.TryParse(value, out var intValue) ? intValue : defaultValue;
        }

        private async Task<string> GetConfigValue(
            IRepository<ConfigModel> repository,
            string key,
            string defaultValue)
        {
            var modelList = await repository.GetAsync(t => t.Key == key);
            return modelList.FirstOrDefault()?.Value ?? defaultValue;
        }

        #endregion

        #region 设置参数

        public async Task SetApiKeyAsync(string value)
        {
            try
            {
                var repository = _container.Resolve<IRepository<ConfigModel>>();
                await UpdateConfigAsync(
                    repository,
                    Constants.ConfigKeys.ApiKey,
                    value
                );
            }
            catch (Exception e)
            {
                _logService.Error($"设置ApiKey失败：{e.GetFullMessage()}.");
            }
        }

        public async Task SetAccountIdAsync(string value)
        {
            try
            {
                var repository = _container.Resolve<IRepository<ConfigModel>>();
                await UpdateConfigAsync(
                    repository,
                    Constants.ConfigKeys.AccountId,
                    value
                );
            }
            catch (Exception e)
            {
                _logService.Error($"设置AccountId失败：{e.GetFullMessage()}.");
            }
        }

        private async Task UpdateConfigAsync(
            IRepository<ConfigModel> repository,
            string key,
            string value
        )
        {
            var model = await repository.GetSingleAsync(t => t.Key == key);
            if (model == null)
            {
                _logService.Warn($"不存在的配置键：{key}");
                return;
            }

            model.Value = value;
            repository.Update(model);
            await repository.SaveAsync();
        }

        #endregion
    }
}
